import React, { Fragment, useState, useMemo } from 'react'
import { observer, useParentForm } from '@formily/react'
import { Space, Steps } from 'antd'
import { Button } from '../../customComponents'
import { FormattedMessage } from '@designable/event-system'
import { TreeNode, createBehavior, createResource } from '@designable/core'
import {
  useNodeIdProps,
  useTreeNode,
  TreeNodeWidget,
  DroppableWidget,
  DnFC,
} from '@designable/react'
import { LoadTemplate } from '../../common/LoadTemplate'
import { createVoidFieldSchema } from '../Field'
import { AllSchemas } from '../../schemas'
import { AllLocales } from '../../locales'
import { matchComponent } from '../../shared'

/**
 * 从给定的父节点中解析出“步骤项（FormStep.StepPane）”列表。
 *
 * 设计器中的表单步骤是由多个子节点组成的，而每一个步骤项都是一个
 * `Field` 节点，其 `props['x-component']` 为 `FormStep.StepPane`。
 *
 * 本函数会：
 * - 仅遍历父节点的第一层子节点（不做递归），以保持与 UI 展示一致的步骤顺序；
 * - 使用 `matchComponent` 精确匹配组件类型，过滤出所有步骤项；
 * - 保留原有顺序，将符合条件的节点依次推入并返回。
 *
 * 之所以不递归查找，是因为步骤项只应由“直接子节点”定义，嵌套层级中的
 * 其他控件不应被视为步骤；这样可以避免误将内部控件识别为步骤。
 *
 * 该函数通常配合 `useMemo(() => parseSteps(node), [node.children])` 使用，
 * 当子节点集合发生变化（增删改排序）时，重新计算步骤列表用于渲染。
 */
const parseSteps = (parent: TreeNode, defaultNode?: TreeNode) => {
  const steps: TreeNode[] = []
  // 仅遍历第一层子节点，保持与设计树中的顺序一致
  parent.children.forEach((node) => {
    // 过滤出 x-component 为 FormStep.StepPane 的节点
    if (matchComponent(node, 'FormStep.StepPane')) {
      steps.push(node)
    }
  })
  if (defaultNode) {
    steps.push(defaultNode)
  }
  // 返回按出现顺序排列的步骤节点数组
  return steps
}

const getCorrectCurrent = (current: number | undefined, steps: TreeNode[]) => {
  if (steps.length === 0) return 0
  if (typeof current !== 'number') return steps.length - 1
  if (current >= 0 && current < steps.length) return current
  return steps.length - 1
}

/**
 * 判断给定的步骤面板节点是否为“完成”步骤。
 * 语言无关：通过检测其子节点中是否存在 `Result` 且 `status === 'success'` 的组件来识别。
 */
const isFinishStep = (stepNode: TreeNode) => {
  if (!stepNode || !stepNode.children) return false
  return stepNode.children.some((child) => {
    if (!child || !child.props) return false
    const xComponent = child.props['x-component']
    const xComponentProps = child.props['x-component-props'] || {}

    return xComponent === 'Result' && xComponentProps.status === 'success'
  })
}

export const FormStep: DnFC<any> & {
  StepPane?: React.FC
} = observer((props) => {
  const nodeId = useNodeIdProps()
  const node = useTreeNode()
  const [current, setCurrent] = useState<number>(0)
  const parentForm = useParentForm?.()

  const finishStep = new TreeNode({
    componentName: 'Field',
    props: {
      type: 'void',
      'x-component': 'FormStep.StepPane',
      'x-component-props': {
        title: '完成',
      },
    },
  })

  // 确保真实存在一个“完成”步骤（作为树节点），避免 target 为空
  React.useEffect(() => {
    if (!node) return
    const existFinish = node.children?.find((child) => {
      if (!matchComponent(child, 'FormStep.StepPane')) return false
      return isFinishStep(child)
    })
    const ensureFinishContent = (target: TreeNode) => {
      // 若已有 Result(success) 子节点，则只更新其标题
      const existingResult = target.children?.find((child) => {
        if (!child || !child.props) return false
        const xComponent = child.props['x-component']
        const xComponentProps = child.props['x-component-props'] || {}
        return xComponent === 'Result' && xComponentProps.status === 'success'
      })
      if (existingResult) {
        const xComponentProps = existingResult.props['x-component-props'] || {}
        existingResult.props['x-component-props'] = {
          ...xComponentProps,
          title: props.resultTitle,
        }
        return
      }
      // 若为空，则补充完成内容
      if (!target.children?.length) {
        const finishContent = new TreeNode({
          componentName: 'Field',
          props: {
            type: 'void',
            'x-component': 'Result',
            'x-component-props': {
              status: 'success',
              title: props.resultTitle,
            },
          },
        })
        target.append(finishContent)
      }
    }
    if (!existFinish) {
      // 优先复用“最后一个且为空”的 StepPane 作为完成步骤，避免新增重复完成步骤
      const lastEmptyStepPane = [...(node.children || [])]
        .reverse()
        .find(
          (child) =>
            matchComponent(child, 'FormStep.StepPane') &&
            !(child.children && child.children.length)
        )
      if (lastEmptyStepPane) {
        ensureFinishContent(lastEmptyStepPane)
      } else {
        node.append(finishStep)
        ensureFinishContent(finishStep)
      }
    } else {
      ensureFinishContent(existFinish)
    }
  }, [node, props.resultTitle])
  const StepPaneBody: React.FC<{ nodeId: string }> = observer((props) => {
    const { nodeId: bodyNodeId } = props
    const target = node.find((n) => {
      return n.id === bodyNodeId
    })
    return (
      <div style={{ padding: '20px 0' }}>
        {target && target.children?.length ? (
          <TreeNodeWidget node={target} />
        ) : target ? (
          <DroppableWidget node={target} />
        ) : null}
      </div>
    )
  })

  const steps = useMemo(() => parseSteps(node), [node.children])
  const renderStepForm = () => {
    const activeIndex = getCorrectCurrent(current, steps)
    const onStepChange = (idx: number) => {
      setCurrent(idx)
    }

    return (
      <div style={props.style}>
        <Steps
          current={activeIndex}
          onChange={onStepChange}
          style={{ marginBottom: 16 }}
        >
          {steps.map((step, idx) => {
            const stepProps = step.props['x-component-props'] || {}
            const title = stepProps.title || `Step ${idx + 1}`
            return (
              <Steps.Step
                key={step.id}
                title={title}
                subTitle={stepProps.subTitle}
                description={stepProps.description}
              />
            )
          })}
        </Steps>
        {/* 渲染当前激活步骤的内容 */}
        {steps[activeIndex] ? (
          <StepPaneBody nodeId={steps[activeIndex].id} />
        ) : null}
        {activeIndex !== steps.length - 1 && (
          <Space
            style={{
              display: 'flex',
              justifyContent: 'center',
              width: '100%',
            }}
          >
            {activeIndex >= 1 && (
              <Button
                size="large"
                onClick={() => setCurrent(Math.max(0, activeIndex - 1))}
              >
                {props.backText}
              </Button>
            )}
            {activeIndex < steps.length - 2 && (
              <Button
                size="large"
                type="primary"
                onClick={async () => {
                  const next = Math.min(steps.length - 1, activeIndex + 1)
                  if (next === activeIndex) return
                  try {
                    if (parentForm) {
                      await parentForm.validate()
                    }
                    setCurrent(next)
                  } catch {}
                }}
              >
                {props.nextText}
              </Button>
            )}
            {activeIndex === steps.length - 2 && (
              <Button
                size="large"
                type="primary"
                onClick={async () => {
                  try {
                    if (parentForm) {
                      await parentForm.validate()
                    }
                    // eslint-disable-next-line no-console
                    console.log('FormStep submit')
                  } catch {}
                }}
              >
                {props.submitText}
              </Button>
            )}
          </Space>
        )}
      </div>
    )
  }
  return (
    <div {...nodeId}>
      {renderStepForm()}
      <LoadTemplate
        actions={[
          {
            title: node.getMessage('addStep'),
            icon: 'AddPanel',
            onClick: () => {
              // 计算新步骤编号（排除“完成”步骤）
              const regularSteps = steps.filter((step) => !isFinishStep(step))
              const stepNumber = regularSteps.length + 1

              const stepPane = new TreeNode({
                componentName: 'Field',
                props: {
                  type: 'void',
                  'x-component': 'FormStep.StepPane',
                  'x-component-props': {
                    title: `Step ${stepNumber}`,
                  },
                },
              })

              // 查找当前树中的“完成”步骤
              const completeStep = steps.find((step) => isFinishStep(step))

              if (completeStep) {
                node.insertChildren(steps.length - 1, stepPane)
                setTimeout(() => setCurrent(steps.length - 1), 0)
              } else {
                node.append(stepPane)
                // 追加到末尾，新步骤的索引是当前数量
                setCurrent(steps.length)
              }
            },
          },
        ]}
      />
    </div>
  )
})

FormStep.StepPane = (props) => {
  return <Fragment>{props.children}</Fragment>
}

FormStep.Behavior = createBehavior(
  {
    name: 'FormStep',
    extends: ['Field'],
    selector: (node) => node.props['x-component'] === 'FormStep',
    designerProps: {
      droppable: true,
      allowAppend: (target, source) =>
        target.children.length === 0 ||
        source.every(
          (node) => node.props['x-component'] === 'FormStep.StepPane'
        ),
      propsSchema: createVoidFieldSchema(AllSchemas.FormStep),
    },
    designerLocales: AllLocales.FormStep,
  },
  {
    name: 'FormStep.StepPane',
    extends: ['Field'],
    selector: (node) => node.props['x-component'] === 'FormStep.StepPane',
    designerProps: {
      droppable: true,
      allowDrop: (node) => node.props['x-component'] === 'FormStep',
      propsSchema: createVoidFieldSchema(AllSchemas.FormStep.StepPane),
    },
    designerLocales: AllLocales.FormStepPane,
  }
)

FormStep.Resource = createResource({
  icon: 'Module',
  elements: [
    {
      componentName: 'Field',
      props: {
        type: 'void',
        title: 'FormStep',
        'x-component': 'FormStep',
      },
    },
  ],
})
